﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Microsoft.Win32;
using System.Windows;
using System.Xml;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Controls;
using System.IO;
using SHomeWorkshop.LunarMind.Converts;

namespace SHomeWorkshop.LunarMind.Commands
{
    /// <summary>
    /// 以此类为模板，制作自定义命令类
    ///     共需要修改１０处！！！
    /// ==============================
    /// 
    /// 导出为图像文件命令。
    /// ★①，修改类名。
    /// </summary>
    public static class OutportToImageFileCommand
    {
        private static RoutedUICommand routedUICmd;//创建私有字段

        public static RoutedUICommand RoutedUICmd//创建只读静态属性
        {
            get { return routedUICmd; }
        }

        /// <summary>
        /// ★②，修改静态构造方法名。
        /// </summary>
        static OutportToImageFileCommand()//类型构造器
        {
            //★③，修改两个字符串参数名。★④以及第三个参数的类型名。
            routedUICmd = new RoutedUICommand(
                "OutportToImageFileCommand",
                "OutportToImageFileCommand",
                typeof(OutportToImageFileCommand),//创建RoutedUICommand对象
                null//不需要快捷键
                );

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        private static CommandBinding cmdBinding = new CommandBinding();

        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            //★⑦，修改此方法的实现。

            OutportToImageFile();
        }

        internal static bool OutportToImageFile(string fileFullPath = null)
        {
            double scale = ScaleValueConverter.GetNewScaleValue(Globals.MainWindow.sliderOfCanvasScale.Value);

            if (scale < 1)
            {
                MessageBoxResult r = MessageBox.Show("　　当前文档的缩放比例小于１，导出的图片文件可能比较模糊。要继续吗？",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (r != MessageBoxResult.Yes) return false;
            }

            RenderTargetBitmap rtb = new RenderTargetBitmap(
                (int)(Globals.MainWindow.mainCanvas.Width * scale) + 2,
                (int)(Globals.MainWindow.mainCanvas.Height * scale) + 2,
                96, 96, PixelFormats.Pbgra32);

            string filename;

            if (fileFullPath == null)
            {
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Title = Globals.AppName + "——导出图片：";
                sfd.Filter = "标记图像格式(*.tiff)|*.tiff|可移植网络图形(*.png)|*.png";
                sfd.FileName = Globals.MainWindow.GetDefaultFileName() + "_文档图";

                if (sfd.ShowDialog() != true) return false;
                filename = sfd.FileName;
            }
            else
            {
                filename = fileFullPath;
            }

            try
            {
                //BitmapEncoder encoder = new PngBitmapEncoder();//分辨率只能是96DPI。
                //BitmapEncoder encoder = new GifBitmapEncoder();//分辨率过低。
                //BitmapEncoder encoder = new JpegBitmapEncoder();//分辨率可以是300DPI，但不支持透明底色。
                BitmapEncoder encoder;

                bool isPng = filename.EndsWith(".png");
                if (isPng)
                {

                    rtb = GetExpressionImage(false); ;//96DPI
                    encoder = new PngBitmapEncoder();
                }
                else
                {
                    rtb = GetExpressionImage();//300DPI
                    encoder = new TiffBitmapEncoder();
                }

                encoder.Frames.Add(BitmapFrame.Create(rtb));
                using (Stream stm = File.Create(filename))
                {
                    encoder.Save(stm);
                }

                if (isPng)
                {
                    using (StreamWriter sw = File.AppendText(filename))
                    {
                        sw.WriteLine();

                        sw.WriteLine("<?Lunar Mind?>");
                        sw.Write(Globals.MainWindow.MainXmlDocument.OuterXml);

                        //刷新“最近文档列表”。
                        RecentFileItem.WriteRecentFilesToXmlFile(filename);
                        RecentFileItem.ReadRecentFilesFromXmlFile();

                        if (fileFullPath == null)
                        {
                            System.Windows.MessageBox.Show("已导出为：" + filename +
                            "\r\n\r\n导出为PNG格式的图片会嵌入文档数据，可以使用本程序重新打开此文档！\r\n" +
                            "★★请勿使用图像编辑软件对导出的 PNG 图片进行编辑，这会破坏该图片文件尾部附加的文档数据。\r\n\r\n" +
                            "★★Tiff格式的图片主要用以打印，【不支持】此功能！",
                            Globals.AppName,
                            MessageBoxButton.OK, MessageBoxImage.Information);
                        }
                        else//非null是“Save()”方法调用。
                        {
                            MainWindow editor = Globals.MainWindow;
                            editor.IsModified = false;
                            editor.ModifingsList.PointOfSaving = editor.ModifingsList.Point;
                        }
                    }
                }
                else
                {
                    System.Windows.MessageBox.Show("已导出为：" + filename +
                        "\r\n\r\n★注意：导出为Tiff格式的图片【不会】嵌入文档数据，因此导出后【不能再用本程序打开】！",
                        Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Information);
                }

                return true;
            }
            catch (Exception ex)
            {
                Dialogs.LunarMsgBox.MsgBoxShow(Globals.AppName,
                    "导出为图像文件时出现异常。异常信息如下：\r\n",
                    ex.Message, ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Error, null,
                    MessageBoxResult.OK, Globals.MainWindow);
                return false;
            }
        }

        /// <summary>
        /// 将整个文档导出为一张图片。
        /// </summary>
        /// <param name="outportExpression">要导出图片的公式。</param>
        /// <param name="withClearnessDPI">是否按照较高的DPI导出（用于打印的图像应使用此值）。
        /// 为True时使用300DPI，为False时使用96DPI。</param>
        /// <returns></returns>
        public static RenderTargetBitmap GetExpressionImage(bool withClearnessDPI = true)
        {
            //Brush back = outportExpression.Editor.BaseScrolledViewer.Background;
            //Brush exBorderBsh = outportExpression.MainBorder.BorderBrush;

            //outportExpression.MainBorder.BorderBrush = back;

            RenderTargetBitmap rtb;
            double scale = ScaleValueConverter.GetNewScaleValue(Globals.MainWindow.sliderOfCanvasScale.Value);

            if (withClearnessDPI)
            {
                rtb = new RenderTargetBitmap(
                    (int)(Globals.MainWindow.mainCanvas.ActualWidth * 3.125 * scale),
                    (int)(Globals.MainWindow.mainCanvas.ActualHeight * 3.125 * scale),
                    300, 300, PixelFormats.Pbgra32);//300÷96=3.125//用来打印的图片分辨率要高些。96DPI只适合屏幕显示。
            }
            else
            {
                rtb = new RenderTargetBitmap(
                    (int)(Globals.MainWindow.mainCanvas.ActualWidth * scale),
                    (int)(Globals.MainWindow.mainCanvas.ActualHeight * scale),
                    96, 96, PixelFormats.Pbgra32);//只在屏幕上显示的图片分辨率可以低些，96DPI就够了。
            }

            rtb.Render(Globals.MainWindow.mainCanvas);
            return rtb;
        }

        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            //★⑧，修改此方法的实现。
            e.CanExecute = true;//总是可以导出图像文件的。
        }
    }
}
